

/* CrawlThread will:
 * - Dequeue an element from the nodeQueue and crawl it. (pull)
 * - Then enqueue its result to the CrawlMaster's writeQueue.
 * - Repeat
 */

public class CrawlThread extends Thread{
	
    private Queue nodeQueue, writeQueue, allHosts;
    int timeout;
    int name;
    
    // Constructor
    public CrawlThread(Queue node, Queue write, Queue hosts, int t, int n) {
    	nodeQueue = node;
    	writeQueue = write;
    	allHosts = hosts;
    	timeout = t;
    	name = n;
    }
    	
	public void run () {
//		System.out.println("Thread " + name + " Started");
		
		String ultraPeer;
		
		while(true) {
			//System.out.println(nodeQueue._queue.toString());
			
			if (Thread.interrupted()) {
//				System.out.println("Thread " + name + " Interrupted");
	        	return;
	        }
				
	        // Get a node from the nodeQueue
			try {
				ultraPeer = (String)nodeQueue.dequeue();
			} catch (InterruptedException e) {
//				System.out.println("Thread " + name + " Interrupted");
				return;
			}
        	String uhost = ultraPeer.split(":")[0];
        	int uport = Integer.parseInt(ultraPeer.split(":")[1]);
        	
        	// Crawl the node
        	System.out.println("Thread " + name + " is Crawling "+uhost+":"+uport);
        	Crawler crawler = new Crawler();
        	CrawlResult crawlResult = crawler.crawl(uhost,uport, timeout);
	        if(crawlResult == null) {
	        	continue;
	        }
//	        crawlResult.print();
	        
	        // Put the Result into the writeQueue
	        writeQueue.enqueue(crawlResult);
	        
	        // Parse for the ultra peers and add them to the nodeQueue
	        if(crawlResult.getUltrapeers() != null) {
	        	String[] ultrapeers = {crawlResult.getUltrapeers()};
		        if( ultrapeers[0].contains(",") ) {
		        	ultrapeers = ultrapeers[0].split(",");
		        }
		        for(int i=0; i<ultrapeers.length; i++) {
		        	if( !ultrapeers[i].isEmpty() && !allHosts.contains(ultrapeers[i]) ) {
		        		nodeQueue.enqueue(ultrapeers[i]);
		        		allHosts.enqueue(ultrapeers[i]);
		        	}
	        	}
	        }
	        
	        // Parse for the leave nodes and add them to our nodeQueue
	        if(crawlResult.getLeaves() != null) {
	        	String[] leaveNodes = {crawlResult.getLeaves()};
		        if( leaveNodes[0].contains(",") ) {
		        	leaveNodes = leaveNodes[0].split(",");
		        }
		        for(int i=0; i<leaveNodes.length; i++) {
		        	if( !leaveNodes[i].isEmpty() && !allHosts.contains(leaveNodes[i]) ) {
		        		nodeQueue.enqueue(leaveNodes[i]);
		        		allHosts.enqueue(leaveNodes[i]);
		        	}
	        	}
	        }
	        
		}
        	
	}
}
